package cn.com.fstar.framework.admin.service;

import cn.com.fstar.core.CodeConstant;
import cn.com.fstar.core.model.Tmodule;
import cn.com.fstar.core.model.Torganization;
import cn.com.fstar.core.model.Trole;
import cn.com.fstar.core.model.Tuser;
import cn.com.fstar.core.pageModel.PageHelper;
import cn.com.fstar.core.pageModel.User;
import cn.com.fstar.core.util.ChineseCharToEn;
import cn.com.fstar.core.util.MD5Util;
import cn.com.fstar.core.util.StringUtil;
import cn.com.fstar.framework.base.dao.BaseDaoI;
import cn.com.fstar.framework.base.model.EasyUIComboTree;
import cn.com.fstar.framework.base.model.EasyUIDataGrid;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class UserService {

    @Autowired
    private BaseDaoI<Tuser> userDao;

    @Autowired
    private BaseDaoI<Trole> roleDao;

    @Autowired
    private BaseDaoI<Tmodule> moduleDao;

    @Autowired
    private BaseDaoI<Torganization> organizationDao;

    public User login(User user) {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("loginName", user.getLoginName());
        params.put("password", MD5Util.md5(user.getPassword()));
        Tuser t = userDao.get("from Tuser t where t.loginName = :loginName and t.password = :password", params);
        if (t != null) {
            BeanUtils.copyProperties(t, user);
            if (t.getTroles() != null && !t.getTroles().isEmpty()) {
                String roleIds = "";
                String roleNames = "";
                boolean b = false;
                for (Trole role : t.getTroles()) {
                    if (b) {
                        roleIds += ",";
                        roleNames += ",";
                    } else {
                        b = true;
                    }
                    roleIds += role.getId();
                    roleNames += role.getRoleName();
                }
                user.setRoleIds(roleIds);
                user.setRoleNames(roleNames);
            }
            return user;
        }
        return null;
    }

    public User loginByLoginName(String loginName) {
        User user = new User();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("loginName", loginName);
        Tuser t = userDao.get("from Tuser t where t.loginName = :loginName", params);
        if (t != null) {
            BeanUtils.copyProperties(t, user);
            if (t.getTroles() != null && !t.getTroles().isEmpty()) {
                String roleIds = "";
                String roleNames = "";
                boolean b = false;
                for (Trole role : t.getTroles()) {
                    if (b) {
                        roleIds += ",";
                        roleNames += ",";
                    } else {
                        b = true;
                    }
                    roleIds += role.getId();
                    roleNames += role.getRoleName();
                }
                user.setRoleIds(roleIds);
                user.setRoleNames(roleNames);
            }
            return user;
        }
        return null;
    }

    synchronized public void reg(User user) throws Exception {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("loginName", user.getLoginName());
        if (userDao.count("select count(*) from Tuser t where t.loginName = :loginName", params) > 0) {
            throw new Exception("登录名已存在！");
        } else {
            Tuser u = new Tuser();
            BeanUtils.copyProperties(user, u);
            u.setId(StringUtil.generateUUID());
            u.setLoginName(user.getLoginName());
            u.setPassword(MD5Util.md5(user.getPassword()));
            u.setUserState(CodeConstant.USER_STATE_NORMAL);
            u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
            u.setCreateDate(new Date());

            userDao.save(u);
        }
    }

    public EasyUIDataGrid dataGrid(User user, PageHelper ph) {
        EasyUIDataGrid dg = new EasyUIDataGrid();
        List<User> ul = new ArrayList<User>();
        Map<String, Object> params = new HashMap<String, Object>();

        String hql = " from Tuser t ";
        List<Tuser> l = userDao.find(hql + whereHql(user, params) + orderHql(ph), params, ph.getPage(), ph.getRows());
        if (l != null && l.size() > 0) {
            for (Tuser t : l) {
                User u = new User();
                BeanUtils.copyProperties(t, u);
                if (t.getTorganization() != null && StringUtils.isNotBlank(t.getTorganization().getOrgName())) {
                    u.setOrganizationName(t.getTorganization().getOrgName());
                }

                Set<Trole> roles = t.getTroles();
                if (roles != null && !roles.isEmpty()) {
                    String roleIds = "";
                    String roleNames = "";
                    boolean b = false;
                    for (Trole tr : roles) {
                        if (b) {
                            roleIds += ",";
                            roleNames += ",";
                        } else {
                            b = true;
                        }
                        roleIds += tr.getId();
                        roleNames += tr.getRoleName();
                    }
                    u.setRoleIds(roleIds);
                    u.setRoleNames(roleNames);
                }
                ul.add(u);
            }
        }
        dg.setRows(ul);
        dg.setTotal(userDao.count("select count(*) " + hql + whereHql(user, params), params));
        return dg;
    }

    private String whereHql(User user, Map<String, Object> params) {
        String hql = "";
        if (user != null) {
            hql += " where 1=1 ";
            if (StringUtils.isNotEmpty(user.getLoginName())) {
                hql += " and t.loginName like :loginName";
                params.put("loginName", "%%" + user.getLoginName() + "%%");
            }
            if (StringUtils.isNotEmpty(user.getUserName())) {
                hql += " and t.userName like :userName";
                params.put("userName", "%%" + user.getUserName() + "%%");
            }
            if (StringUtils.isNotEmpty(user.getUserState())) {
                hql += " and t.userState = :userState";
                params.put("userState", user.getUserState());
            }
            if (user.getCreateDateStart() != null) {
                hql += " and t.createDate >= :createDateStart";
                params.put("createDateStart", user.getCreateDateStart());
            }
            if (user.getCreateDateEnd() != null) {
                hql += " and t.createDate <= :createDateEnd";
                params.put("createDateEnd", user.getCreateDateEnd());
            }
            if (user.getUpdateDateStart() != null) {
                hql += " and t.updateDate >= :updateDateStart";
                params.put("updateDateStart", user.getUpdateDateStart());
            }
            if (user.getUpdateDateEnd() != null) {
                hql += " and t.updateDate <= :updateDateEnd";
                params.put("updateDateEnd", user.getUpdateDateEnd());
            }
        }
        return hql;
    }

    private String orderHql(PageHelper ph) {

        String orderString = " order by t.userState asc";
        if (ph.getSort() != null && ph.getOrder() != null) {
            orderString += " ,t." + ph.getSort() + " " + ph.getOrder();
        }
        return orderString;
    }

    synchronized public void add(User user) throws Exception {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("loginName", user.getLoginName());
        if (userDao.count("select count(*) from Tuser t where t.loginName = :loginName", params) > 0) {
            throw new Exception("登录名已存在！");
        } else {
            Tuser u = new Tuser();
            BeanUtils.copyProperties(user, u);
            u.setId(StringUtil.generateUUID());
            u.setCreateDate(new Date());
            u.setPassword(MD5Util.md5(user.getPassword()));
            u.setUserState(CodeConstant.USER_STATE_NORMAL);
            u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
            u.setTorganization(organizationDao.get(Torganization.class, user.getOrganizationId().trim()));
            userDao.save(u);
        }
    }

    public User get(String id) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", id);
        Tuser t = userDao.get("select distinct t from Tuser t left join fetch t.troles role where t.id = :id", params);
        User u = new User();
        BeanUtils.copyProperties(t, u);
        if (t.getTroles() != null && !t.getTroles().isEmpty()) {
            String roleIds = "";
            String roleNames = "";
            boolean b = false;
            for (Trole role : t.getTroles()) {
                if (b) {
                    roleIds += ",";
                    roleNames += ",";
                } else {
                    b = true;
                }
                roleIds += role.getId();
                roleNames += role.getRoleName();
            }

            u.setRoleIds(roleIds);
            u.setRoleNames(roleNames);
        }
        Torganization org = t.getTorganization();
        if (org != null && StringUtils.isNotBlank(org.getOrgName())) {
            u.setOrganizationId(org.getId());
            u.setOrganizationName(org.getOrgName());
        }
        return u;
    }

    synchronized public void edit(User user) throws Exception {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", user.getId());
        params.put("loginName", user.getLoginName());
        if (userDao.count("select count(*) from Tuser t where t.loginName = :loginName and t.id != :id", params) > 0) {
            throw new Exception("登录名已存在！");
        } else {

            Tuser u = userDao.get(Tuser.class, user.getId());
            u.setTorganization(organizationDao.get(Torganization.class, user.getOrganizationId().trim()));

            BeanUtils.copyProperties(user, u, new String[] { "password", "createDate" });
            u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
            u.setUpdateDate(new Date());
            userDao.save(u);
        }
    }

    /**
     * 删除用户：非物理删除，但是会删除与该用户相关的对象关联信息删除。比如（角色/组织机构）
     * 
     * @param id
     */
    public void delete(String id) {

        Tuser tuser = userDao.get(Tuser.class, id);

        tuser.setTroles(null);
        tuser.setTorganization(null);
        tuser.setUserState(CodeConstant.USER_STATE_DELETE);
        userDao.update(tuser);
    }

    /**
     * 还原用户
     * 
     * @param id
     */
    public void recovery(String id) {
        Tuser tuser = userDao.get(Tuser.class, id);
        tuser.setUserState(CodeConstant.USER_STATE_NORMAL);
        userDao.update(tuser);
    }

    /**
     * 用户授权，需要参数为userId与roleIds两个参数
     * @param user
     * @return
     */
    public String grant(String userId, String roleIds) {

        List<Trole> roles = new ArrayList<Trole>();
        if (roleIds!= null) {
            for (String roleId : roleIds.split(",")) {
                roles.add(roleDao.get(Trole.class, roleId));
            }
        }

        Tuser t = userDao.get(Tuser.class, userId);
        t.setTroles(new HashSet<Trole>(roles));

        return null;
    }

    public List<String> moduleList(User user) {
        List<String> moduleList = new ArrayList<String>();
        if (user.getLoginName().equals(CodeConstant.SUPER_USER_LOGIN_NAME)) {
            List<Tmodule> list = moduleDao.find("from Tmodule");
            if (list != null && list.size() > 0) {
                for (Tmodule Tmodule : list) {
                    moduleList.add(Tmodule.getModuleUrl());
                }
            }
        } else {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("id", user.getId());
            Tuser t = userDao.get(
                    "from Tuser t join fetch t.troles role join fetch role.tmodules module where t.id = :id", params);
            if (t != null) {
                Set<Trole> roles = t.getTroles();
                if (roles != null && !roles.isEmpty()) {
                    for (Trole role : roles) {
                        Set<Tmodule> resources = role.getTmodules();
                        if (resources != null && !resources.isEmpty()) {
                            for (Tmodule resource : resources) {
                                if (resource != null && resource.getModuleUrl() != null) {
                                    moduleList.add(resource.getModuleUrl());
                                }
                            }
                        }
                    }
                }
            }
        }
        return moduleList;
    }

    public void editPwd(User user) {
        if (user != null && user.getPassword() != null && !user.getPassword().trim().equalsIgnoreCase("")) {
            Tuser u = userDao.get(Tuser.class, user.getId());
            u.setPassword(MD5Util.md5(user.getPassword()));
        }
    }

    public boolean editCurrentUserPwd(String userId, String oldPwd, String pwd) {
        Tuser u = userDao.get(Tuser.class, userId);
        if (u.getPassword().equalsIgnoreCase(MD5Util.md5(oldPwd))) {// 说明原密码输入正确
            u.setPassword(MD5Util.md5(pwd));
            return true;
        }
        return false;
    }

    public List<Long> userCreateDatetimeChart() {
        List<Long> l = new ArrayList<Long>();
        int k = 0;
        for (int i = 0; i < 12; i++) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("s", k);
            params.put("e", k + 2);
            k = k + 2;
            l.add(userDao.count("select count(*) from Tuser t where HOUR(t.createDate)>=:s and HOUR(t.createDate)<:e",
                    params));
        }
        return l;
    }

    /**
     * 根据用户登录名获取用户信息
     * 
     * @param loginName
     * @return
     */
    public User getUserByLoginName(String loginName) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("loginName", loginName);
        Tuser t = userDao.get("from Tuser t where t.loginName = :loginName ", params);
        User user = new User();
        if (t != null) {
            BeanUtils.copyProperties(t, user);
            if (t.getTroles() != null && !t.getTroles().isEmpty()) {
                String roleIds = "";
                String roleNames = "";
                boolean b = false;
                for (Trole role : t.getTroles()) {
                    if (b) {
                        roleIds += ",";
                        roleNames += ",";
                    } else {
                        b = true;
                    }
                    roleIds += role.getId();
                    roleNames += role.getRoleName();
                }
                user.setRoleIds(roleIds);
                user.setRoleNames(roleNames);
            }
            return user;
        }
        return null;
    }

    public List<EasyUIComboTree> getuser() {

        String hql = " from Tuser t";

        List<Tuser> list = userDao.find(hql);
        List<EasyUIComboTree> liste = new ArrayList<EasyUIComboTree>();
        if (list != null && list.size() > 0) {
            for (Tuser tuser : list) {
                EasyUIComboTree et = new EasyUIComboTree();
                et.setId(tuser.getId());
                et.setText(tuser.getLoginName());
                liste.add(et);
            }
        }
        return liste;
    }
}
